﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using Thirteen23.TED.Data;
using Thirteen23.TED.Models;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Notifications;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace Thirteen23.TED.Views
{
    public sealed partial class TalkPage
    {
        private DispatcherTimer _timer = new DispatcherTimer();

        public TedTalk Talk { get; set; }

        public TalkPage()
        {
            InitializeComponent();

            _timer.Interval = TimeSpan.FromSeconds(3);
            _timer.Tick += delegate
            {
                _timer.Stop();
                VisualStateManager.GoToState(this, "ControlsHidden", true);
            };
            _timer.Start();
        }

        // View state management for switching among Full, Fill, Snapped, and Portrait states

        private DisplayPropertiesEventHandler _displayHandler;
        private TypedEventHandler<ApplicationLayout, ApplicationLayoutChangedEventArgs> _layoutHandler;

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            if (_displayHandler == null)
            {
                _displayHandler = Page_OrientationChanged;
                _layoutHandler = Page_LayoutChanged;
            }
            DisplayProperties.OrientationChanged += _displayHandler;
            ApplicationLayout.GetForCurrentView().LayoutChanged += _layoutHandler;
            SetCurrentOrientation(this);
            MediaElement.MediaOpened += OnMediaOpened;
        }

        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
            DisplayProperties.OrientationChanged -= _displayHandler;
            ApplicationLayout.GetForCurrentView().LayoutChanged -= _layoutHandler;
            MediaElement.MediaOpened -= OnMediaOpened;
        }

        private void Page_LayoutChanged(object sender, ApplicationLayoutChangedEventArgs e)
        {
            SetCurrentOrientation(this);
        }

        private void Page_OrientationChanged(object sender)
        {
            SetCurrentOrientation(this);
        }

        private void SetCurrentOrientation(Control viewStateAwareControl)
        {
            VisualStateManager.GoToState(viewStateAwareControl, this.GetViewState(), false);
        }

        private String GetViewState()
        {
            var orientation = DisplayProperties.CurrentOrientation;
            if (orientation == DisplayOrientations.Portrait ||
                orientation == DisplayOrientations.PortraitFlipped) return "Portrait";
            var layout = ApplicationLayout.Value;
            if (layout == ApplicationLayoutState.Filled) return "Fill";
            if (layout == ApplicationLayoutState.Snapped) return "Snapped";
            return "Full";
        }

        private void BackButtonClicked(object sender, RoutedEventArgs e)
        {
            MediaElement.Stop();
            MediaElement.PointerReleased -= OnPointerReleased;
            ApplicationModel.Instance.NavigateBack();
        }

        protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            this.Talk = e.Parameter as TedTalk;
            this.TitleText.Text = Talk.SanitizedTitle;
            this.AuthorText.Text = Talk.Author;

            MediaElement.Source = new Uri(Talk.MediaLocation, UriKind.Absolute);
            MediaElement.Play();
        }

        private void OnMediaOpened(object sender, RoutedEventArgs e)
        {
            VisualStateManager.GoToState(this, "NotLoading", true);

            MediaElement.Visibility = Windows.UI.Xaml.Visibility.Visible;
            MediaElement.BufferingProgressChanged += new RoutedEventHandler(MediaElement_BufferingProgressChanged);

            ProgressSlider.Minimum = 0;
            ProgressSlider.Maximum = MediaElement.NaturalDuration.TimeSpan.TotalSeconds;

            ProgressSlider.ValueChanged += new RoutedPropertyChangedEventHandler(ProgressSlider_ValueChanged);
            DispatcherTimer timer = new DispatcherTimer();
            timer.Tick += (s, args) =>
            {
                if (Math.Abs(ProgressSlider.Value - (MediaElement.Position.TotalSeconds / MediaElement.NaturalDuration.TimeSpan.TotalSeconds)) < 1)
                {
                    ProgressSlider.Value = MediaElement.Position.TotalSeconds;
                }
            };
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Start();
        }

        private void MediaElement_BufferingProgressChanged(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine(MediaElement.BufferingProgress);
        }

        private void ProgressSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
        {
            MediaElement.Position = TimeSpan.FromSeconds(ProgressSlider.Value);
        }

        private void OnPointerReleased(object sender, PointerEventArgs e)
        {
            _timer.Stop();

            if (MediaElement.CurrentState == MediaElementState.Playing ||
                MediaElement.CurrentState == MediaElementState.Buffering)
            {
                MediaElement.Pause();
                PauseIndicator.Visibility = Visibility.Visible;

                VisualStateManager.GoToState(this, "ControlsShowing", true);
            }
            else
            {
                MediaElement.Play();
                PauseIndicator.Visibility = Visibility.Collapsed;

                VisualStateManager.GoToState(this, "ControlsHidden", true);
            }
        }
    }
}
